package api

import (
	"cgs-server/helper"
	"cgs-server/server"
	"cgs-server/server/base"
	"cgs-server/server/cgs/app/models"
	"cgs-server/server/cgs/app/models/dto"
	"cgs-server/server/cgs/app/service"
	"cgs-server/server/cgs/app/store"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"mime/multipart"
	"net/http"
	"net/url"
)

type WorksheetPrintHandler struct {
	// srv service
	srv service.Service
	// store
	store store.Factory
}

func NewWorksheetPrintHandler(store store.Factory) *WorksheetPrintHandler {
	return &WorksheetPrintHandler{
		srv:   service.NewService(store),
		store: store,
	}
}

func (wg *WorksheetPrintHandler) Render(w http.ResponseWriter, r *http.Request) {
	var wp dto.WorksheetPrint
	err := helper.ReadRequestBody(&wp, w, r)
	if err != nil {
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	result, err := wg.srv.WorksheetPrint().Render(&wp, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(bson.M{
		"renderPath": result.Data["renderPath"],
	}))
}

func (wg *WorksheetPrintHandler) Get(w http.ResponseWriter, r *http.Request) {
	groupId := r.FormValue("id")
	if groupId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("id is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	group, err := wg.srv.WorksheetPrint().Detail(groupId, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(group))
}

func (wg *WorksheetPrintHandler) Delete(w http.ResponseWriter, r *http.Request) {
	groupId := r.FormValue("id")
	if groupId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("group id is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetPrint().Delete(groupId, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK())
}

func (wg *WorksheetPrintHandler) Save(w http.ResponseWriter, r *http.Request) {

	err := r.ParseMultipartForm(100 << 20)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	files := r.MultipartForm.File
	file := files["file"][0]
	worksheetId := r.FormValue("worksheetId")
	if worksheetId == "" {
		helper.WriteJSON(w, server.Fail("worksheetId is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	wp := models.WorksheetPrint{
		WorksheetId: worksheetId,
	}
	err = wg.srv.WorksheetPrint().Save(file, &wp, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(bson.M{"id": wp.GetId()}))
}

func (wg *WorksheetPrintHandler) Update(w http.ResponseWriter, r *http.Request) {
	err := r.ParseMultipartForm(100 << 20)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	files := r.MultipartForm.File
	var file *multipart.FileHeader
	if f, ok := files["file"]; ok {
		if len(f) > 0 {
			file = f[0]
		}
	}
	id, err := primitive.ObjectIDFromHex(r.FormValue("id"))
	if err != nil {
		helper.WriteJSON(w, server.Fail("id is required"))
		return
	}
	name := r.FormValue("name")
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	wp := models.WorksheetPrint{
		Name: name,
		Id:   id,
	}
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	err = wg.srv.WorksheetPrint().Update(file, &wp, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK())
}

func (wg *WorksheetPrintHandler) List(w http.ResponseWriter, r *http.Request) {
	worksheetId := r.FormValue("worksheetId")
	if worksheetId == "" {
		_, _ = helper.WriteJSON(w, server.Fail("worksheetId is required"))
		return
	}
	user, err := base.GetCurrentUser(r)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	list, err := wg.srv.WorksheetPrint().ListByWorksheetId(worksheetId, user)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}
	_, _ = helper.WriteJSON(w, server.OK().WithData(list))
}

func (wg *WorksheetPrintHandler) GetFile(w http.ResponseWriter, r *http.Request) {
	templateId := r.FormValue("templateId")
	worksheetId := r.FormValue("worksheetId")
	rowId := r.FormValue("rowId")
	renderPath := r.FormValue("renderPath")

	wf := dto.WorksheetPrintFile{
		TemplateId:  templateId,
		WorksheetId: worksheetId,
		RowId:       rowId,
		RenderPath:  renderPath,
	}

	res, err := wg.srv.WorksheetPrint().GetFile(&wf)
	if err != nil {
		_, _ = helper.WriteJSON(w, server.Fail(err.Error()))
		return
	}

	head := w.Header()
	data := url.Values{}
	data.Set("filename", res.Name)
	head.Set("Content-Disposition", "attachment;"+data.Encode())
	_, _ = w.Write(res.Body)
}
